using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Reflection;
using System.Linq;

class MYReFlection
{
    public static IEnumerable<Type> GetChildInAssembly(Type Base)
    {
        return Assembly.GetExecutingAssembly().GetTypes().Where(item => item.IsSubclassOf(Base));

    }
    public static IEnumerable<Type> GetChildInAssemblys(Type Base)
    {
        return AppDomain.CurrentDomain.GetAssemblies().SelectMany(item => item.GetTypes()).Where(item => item.IsSubclassOf(Base));
    }
    public static IEnumerable<Type> GetInterFaceChildInAssembly(Type Base)
    {
        return Assembly.GetExecutingAssembly().GetTypes()
            .Where(item =>
                item.GetInterfaces().Contains(Base)
                );
    }
    public static IEnumerable<Type> GetInterFaceChildInAssemblys(Type Base)
    {
        return AppDomain.CurrentDomain.GetAssemblies()
                       .SelectMany(item => item.GetTypes())
           .Where(item =>
               item.GetInterfaces().Contains(Base)
               );
    }
    public static T CreateInstance<T>(string assemblyName, string type)
    {
        try
        {
            string fullName = type;
            object ect = Assembly.Load(assemblyName).CreateInstance(fullName);
            return (T)ect;
        }
        catch
        {
            return default(T);
        }
    }
    public static T CreateInstance<T>(T t)
    {
        try
        {
            return (T)Activator.CreateInstance(t.GetType());
        }
        catch
        {
            return default(T);
        }
    }
    public static T CreateInstance<T>(Type t)
    {
        try
        {
            return (T)Activator.CreateInstance(t);
        }
        catch
        {
            return default(T);
        }
    }
    public static Assembly GetCallingAssembly()
    {
        return Assembly.GetCallingAssembly();
    }
    public static string GetCallingAssemblyName()
    {
        return Assembly.GetCallingAssembly().FullName;
    }
    public static Assembly GetCurrentAssembly()
    {
        return Assembly.GetExecutingAssembly();
    }
    public static string GetCurrentAssemblyName()
    {
        return Assembly.GetExecutingAssembly().FullName;
    }
    public static FieldInfo[] GetFieldInfos<T>(T t)
    {
        return t.GetType().GetFields();
    }
    public static FieldInfo[] GetFieldInfos(Type type)
    {
        return type.GetFields();
    }
    public static string GetFieldName(FieldInfo fieldInfo)
    {
        return fieldInfo.Name;
    }
    public static object GetFieldValue(object obj, FieldInfo fieldInfo)
    {
        return fieldInfo.GetValue(obj);
    }
    public static Type GetFieldType(FieldInfo fieldInfo)
    {
        return fieldInfo.FieldType;
    }
    public static PropertyInfo[] GetPropertyInfos<T>(T t)
    {
        return t.GetType().GetProperties();
    }
    public static PropertyInfo[] GetPropertyInfos(Type type)
    {
        return type.GetProperties();
    }
    public static string GetPropertyName(PropertyInfo fieldInfo)
    {
        return fieldInfo.Name;
    }
    public static Type GetPropertyType(PropertyInfo fieldInfo)
    {
        return fieldInfo.PropertyType;
    }
    public static object GetPropertyValue(object obj, PropertyInfo fieldInfo)
    {
        return fieldInfo.GetValue(obj,null);
    }
    public static MethodInfo[] GetMethod(Type type)
    {
        return type.GetMethods();
    }
    public static MethodInfo[] GetMethod<T>(T t)
    {
        return t.GetType().GetMethods();
    }
    public static string GetMethodName(MethodInfo methodInfo)
    {
        return methodInfo.Name;
    }
    public static Type GetMethodReturnType(MethodInfo methodInfo)
    {
        return methodInfo.ReturnType;
    }
    public static ParameterInfo[] GetMethodParameters(MethodInfo methodInfo)
    {
        return methodInfo.GetParameters();
    }
    public static string GetTypeName(Type type)
    {
        return type.Name;
    }
    public static string GetTypeFullName(Type type)
    {
        return type.ToString();
    }
    public static Array GetEnums(Type type)
    {
        return Enum.GetValues(type);
    }
    public static Array GetEnums<T>(T t)
    {
        return Enum.GetValues(t.GetType());
    }
    public static string[] GetEnumNames(Type type)
    {
        return Enum.GetNames(type);
    }
}
